/*
 *  SyncIT , easy synchronization of files between computers and devices.
 *  Copyright (C) 2011  Christian Masus <cmasus(at)gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version. If redistributing and/or modifying
 *  this file, this notice must be included in the redistributed or
 *  modified copy.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import config.ConfigInterface;

/**
 * Takes care of the storing and reading of log files from permanent storage.
 * @author Christian Masus
 *
 */
public class HandleLogFiles {

	private final String LOG_FILE = "log.";

	private ConfigInterface config;
	private OutputStreamWriter out;
	private BufferedReader in;
	private long currentLogSize; 


	public HandleLogFiles(ConfigInterface config) {
		this.config = config;
	}

	/**
	 * Must be called before any this function is used.
	 * @return true if streams are successfully opened to the log file.
	 */
	public boolean init() {
		String logFile = logFilePath( config.getVariableInteger("log", "CurrentFileNumber") );
		try {
			openFileOutBuf(logFile, true);
			currentLogSize = new File(logFile).length();
			return true;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * Closes the streams to the log file.
	 * @return true if streams are successfully closed.
	 */
	public boolean close() {
		try {
			closeFileInBuf();
			closeFileOutBuf();
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	private String logFilePath(int currentFileNumber) {
		return config.getConfigPath() + File.separator + LOG_FILE + currentFileNumber;
	}

	private void openFileOutBuf(String logFile, boolean append) throws UnsupportedEncodingException, FileNotFoundException {
		out = new OutputStreamWriter(new FileOutputStream(logFile, append), "UTF-8");
	}

	private void closeFileOutBuf() throws IOException {
		if(out != null) {
			out.flush();
			out.close();
		}
	}

	private void openFileInBuf(String logFile) throws UnsupportedEncodingException, FileNotFoundException {
		in = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), "UTF-8"));
	}

	private void closeFileInBuf() throws IOException {
		if(in != null) {
			in.close();
		}
	}



	public boolean log(String text) {
		try {
			byte[] textBytes = text.getBytes("UTF8");
			out.write(text);
			currentLogSize += textBytes.length;
			if(currentLogSize >= config.getVariableInteger("log", "MaxFileSize")) {
				out.write("----Wrapping log file----\r\n");
				out.flush();
				return changeLogFile();
			}
			out.flush();
			return true;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * Closes the current log file and opens the next log file and starts writing it from scratch.
	 * @return true if everything went well, otherwise false.
	 */
	private boolean changeLogFile() {
		try {
			closeFileOutBuf();
			int currentFileNumber = config.getVariableInteger("log", "CurrentFileNumber");
			int maxLogFiles = config.getVariableInteger("log", "MaxLogFiles");
			int newCurrentFileNumber = (currentFileNumber % maxLogFiles) + 1; // Range from 1 to maxLogFiles
			config.setVariable("log", "CurrentFileNumber", newCurrentFileNumber);
			String logFile = logFilePath(newCurrentFileNumber);
			openFileOutBuf(logFile, false);
			currentLogSize = 0;
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

}
